package com.ailanyin.admin.modules.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.ailanyin.admin.modules.system.mapper.SysConfigMapper;
import com.ailanyin.admin.modules.system.model.SysConfig;
import com.ailanyin.admin.modules.system.service.SysConfigService;
import com.ailanyin.common.constant.SystemConstants;
import com.ailanyin.common.constant.UserConstants;
import com.ailanyin.common.exception.Asserts;
import com.ailanyin.common.service.RedisService;
import com.ailanyin.security.utils.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author ailanyin
 * @version 1.0
 * @since 2021/10/15 0015 下午 16:44
 */
@Service
public class SysConfigServiceImpl implements SysConfigService {

    @Autowired
    private RedisService redisService;
    @Resource
    private SysConfigMapper configMapper;

    @Override
    public List<SysConfig> selectConfigList(SysConfig config) {
        return configMapper.selectConfigList(config);
    }

    /**
     * 加载参数缓存数据
     */
    @Override
    public void loadingConfigCache() {
        List<SysConfig> configsList = configMapper.selectConfigList(new SysConfig());
        configsList
                .stream()
                .filter(config -> StrUtil.isNotBlank(config.getConfigKey()) && StrUtil.isNotBlank(config.getConfigValue()))
                .forEach(this::addToRedis);
    }

    @Override
    public String selectConfigByKey(String configKey) {

        if (redisService.hasKey(SystemConstants.SYS_CONFIG_REDIS_KEY + configKey)) {
            return redisService.get(SystemConstants.SYS_CONFIG_REDIS_KEY + configKey).toString();
        }
        SysConfig config = new SysConfig();
        config.setConfigKey(configKey);
        SysConfig retConfig = configMapper.selectConfig(config);
        if (ObjectUtil.isNotEmpty(retConfig)) {
            addToRedis(retConfig);
            return retConfig.getConfigValue();
        }
        return null;
    }

    /**
     * 查询参数配置信息
     *
     * @param configId 参数配置ID
     * @return SysConfig 参数配置信息
     */
    @Override
    public SysConfig selectConfigById(Long configId) {
        SysConfig config = new SysConfig();
        config.setConfigId(configId);
        return configMapper.selectConfig(config);
    }

    /**
     * 新增参数配置
     *
     * @param config 参数配置信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addSysConfig(SysConfig config) {
        if (checkConfigKeyNotUnique(config)) {
            Asserts.fail("新增参数'" + config.getConfigName() + "'失败，参数键名已存在");
        }
        config.setCreateBy(SecurityUtil.getLoginUsername());
        config.setCreateTime(new Date());

        int row = configMapper.insertConfig(config);
        if (row > 0) {
            addToRedis(config);
        }
    }

    /**
     * 校验参数键名是否唯一
     *
     * @param config 参数信息
     * @return 结果
     */
    @Override
    public boolean checkConfigKeyNotUnique(SysConfig config) {
        SysConfig info = configMapper.checkConfigKeyUnique(config.getConfigKey());
        return ObjectUtil.isNotEmpty(info) && !info.getConfigId().equals(config.getConfigId());

    }

    /**
     * 修改参数配置
     *
     * @param config 参数配置信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSysConfig(SysConfig config) {

        if (checkConfigKeyNotUnique(config)) {
            Asserts.fail(StrUtil.format(SystemConstants.SYS_CONFIG_EXIST_ERROR, config.getConfigName()));
        }
        int row = configMapper.updateConfig(config);
        if (row > 0) {
            addToRedis(config);
        }
    }

    /**
     * 批量删除参数信息
     *
     * @param configIds 需要删除的参数ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteConfigByIds(Long[] configIds) {
        for (Long configId : configIds) {
            SysConfig config = selectConfigById(configId);
            if (UserConstants.YES.equals(config.getConfigType())) {
                if (configId < SystemConstants.SYS_CONFIG_MAXIMUM_ID) {
                    Asserts.fail(SystemConstants.SYS_CONFIG_NOT_ALLOW_DELETE);
                }
                Asserts.fail(StrUtil.format(SystemConstants.ORIGINAL_CONFIG_NOT_ALLOW_DELETE, config.getConfigKey()));
            }
            configMapper.deleteConfigById(configId);
            delFromRedis(config.getConfigKey());
        }
    }


    private void addToRedis(SysConfig config) {
        redisService.set(SystemConstants.SYS_CONFIG_REDIS_KEY + config.getConfigKey(), config.getConfigValue());
    }

    private void delFromRedis(String configKey) {
        redisService.del(SystemConstants.SYS_CONFIG_REDIS_KEY + configKey);
    }
}
